<template>
  <!-- 自定义弹窗示例：点击点/线/面/模型展示信息 -->
  <div class="page-wrap">
    <CesiumViewer
      ref="viewerComp"
      :options="viewerOptions"
      :camera="camera"
      :homeZoomOutFactor="0.4"
    >
      <template #entities>
        <!-- 点 -->
        <PointEntity :position="pointPos" :pixelSize="12" color="#ff4d4f" />
        <!-- 线 -->
        <PolylineEntity :positions="linePos" :width="4" :material="'#00e5ff'" />
        <!-- 面 -->
        <PolygonEntity
          :positions="polyPos"
          material="rgba(0,229,255,0.25)"
          outlineColor="#00e5ff"
        />
        <!-- 模型 -->
        <ModelEntity
          :position="modelPos"
          url="https://cesium.com/downloads/cesiumjs/releases/1.115/Apps/SampleData/models/CesiumMan/Cesium_Man.glb"
          :scale="1"
          :minimumPixelSize="64"
        />
      </template>
    </CesiumViewer>

    <!-- 自定义弹窗：跟随屏幕坐标定位 -->
    <div
      v-if="popup.visible"
      class="popup"
      :style="{ left: popup.left + 'px', top: popup.top + 'px' }"
    >
      <div class="title">{{ popup.title }}</div>
      <div class="content">
        <pre>{{ popup.info }}</pre>
      </div>
      <div class="actions">
        <el-button size="small" type="primary" @click="popup.visible = false"
          >关闭</el-button
        >
      </div>
    </div>
  </div>
</template>

<script setup>
// 页面：自定义弹窗示例（拾取点/线/面/模型并显示信息）
import { ref, nextTick, onMounted, onBeforeUnmount } from "vue";
import * as Cesium from "cesium";
import CesiumViewer from "@/components/cesium/CesiumViewer.vue";
import PointEntity from "@/components/cesium/PointEntity.vue";
import PolylineEntity from "@/components/cesium/PolylineEntity.vue";
import PolygonEntity from "@/components/cesium/PolygonEntity.vue";
import ModelEntity from "@/components/cesium/ModelEntity.vue";

// 基本视图配置
const viewerOptions = {
  animation: false,
  baseLayerPicker: false,
  geocoder: false,
  timeline: false,
  fullscreenButton: true,
  sceneModePicker: true,
};
const camera = {
  lon: 104.195397,
  lat: 35.86166,
  height: 12000000,
  heading: 0,
  pitch: -45,
  roll: 0,
};

// 示例实体数据
const pointPos = { lon: 116.397, lat: 39.909, height: 0 };
const linePos = [
  { lon: 116.39, lat: 39.9, height: 0 },
  { lon: 121.47, lat: 31.23, height: 0 },
];
const polyPos = [
  { lon: 112.9388, lat: 28.2282, height: 0 },
  { lon: 114.3054, lat: 30.5931, height: 0 },
  { lon: 113.6254, lat: 34.7466, height: 0 },
];
const modelPos = { lon: 113.2644, lat: 23.1291, height: 0 };

// 引用与事件
const viewerComp = ref(null);
const viewer = ref(null);
let handler = null;

// 弹窗状态
const popup = ref({ visible: false, left: 0, top: 0, title: "", info: "" });

onMounted(() => {
  nextTick(() => {
    if (viewerComp.value && typeof viewerComp.value.getViewer === "function")
      viewer.value = viewerComp.value.getViewer();
    const v = viewer.value;
    if (!v) return;

    handler = new Cesium.ScreenSpaceEventHandler(v.scene.canvas);
    handler.setInputAction((movement) => {
      // 1) 屏幕拾取（优先 pick，不中则 drillPick 尝试拾取被覆盖对象）
      let picked = v.scene.pick(movement.position);
      if (!picked) {
        const picks = v.scene.drillPick(movement.position) || [];
        picked = picks.length ? picks[0] : null;
      }
      if (!picked || !picked.id) {
        popup.value.visible = false;
        return;
      }

      // 2) 获取拾取到的实体（确保是 Cesium.Entity）
      const entity = picked.id;

      // 3) 计算弹窗屏幕位置（直接使用点击的屏幕坐标，更稳定）
      const pos = movement.position;

      // 4) 根据实体类型组织展示信息
      let title = "实体";
      let infoObj = {};
      if (entity.point) {
        title = "点信息";
        const cart =
          entity.position &&
          (entity.position.getValue
            ? entity.position.getValue(Cesium.JulianDate.now())
            : entity.position);
        if (cart) {
          const carto = Cesium.Cartographic.fromCartesian(cart);
          const lon = Cesium.Math.toDegrees(carto.longitude).toFixed(6);
          const lat = Cesium.Math.toDegrees(carto.latitude).toFixed(6);
          infoObj = { 类型: "点", 经度: lon, 纬度: lat };
        } else {
          infoObj = { 类型: "点" };
        }
      } else if (entity.polyline) {
        title = "线信息";
        const arr =
          entity.polyline.positions &&
          (entity.polyline.positions.getValue
            ? entity.polyline.positions.getValue(Cesium.JulianDate.now())
            : entity.polyline.positions);
        const count = Array.isArray(arr) ? arr.length : 0;
        infoObj = { 类型: "线", 节点数: count };
      } else if (entity.polygon) {
        title = "面信息";
        infoObj = { 类型: "面" };
      } else if (entity.model) {
        title = "模型信息";
        const cart =
          entity.position &&
          (entity.position.getValue
            ? entity.position.getValue(Cesium.JulianDate.now())
            : entity.position);
        if (cart) {
          const carto = Cesium.Cartographic.fromCartesian(cart);
          const lon = Cesium.Math.toDegrees(carto.longitude).toFixed(6);
          const lat = Cesium.Math.toDegrees(carto.latitude).toFixed(6);
          infoObj = { 类型: "模型", 经度: lon, 纬度: lat };
        } else {
          infoObj = { 类型: "模型" };
        }
      }
      popup.value = {
        visible: true,
        left: pos.x + 10,
        top: pos.y + 10,
        title,
        info: JSON.stringify(infoObj, null, 2),
      };
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  });
});

onBeforeUnmount(() => {
  if (handler) {
    handler.destroy();
    handler = null;
  }
});
</script>

<style scoped>
.page-wrap {
  position: relative;
  width: 100%;
  height: 100%;
}
.popup {
  position: absolute;
  min-width: 180px;
  max-width: 320px;
  background: #fff;
  border: 1px solid #e5e5e5;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  border-radius: 6px;
  padding: 8px 10px;
  z-index: 999; /* 确保在地图之上，但仅覆盖自身区域 */
}
.popup .title {
  font-weight: 600;
  margin-bottom: 6px;
}
.popup .content {
  font-size: 12px;
  color: #333;
  white-space: pre-wrap;
}
.popup .actions {
  margin-top: 6px;
  text-align: right;
}
</style>
